<template>
  <div class="left-nav-container">
    <div class="logo cursor-pointer" @click="handleToHome">
      <!-- {{ systemInfo.companyName || '企业网盘' }} -->
      <n-avatar :src="LogoPng" round :size="48" />
    </div>
    <div class="nav-bar">
      <div class="menu-list">
        <div class="item active" @click="handleToHome">
          <SvgIcon icon="wenjianjia1" color="#cbd3f5" size="20px"></SvgIcon>
          <span class="mt-1">文件管理</span>
        </div>
      </div>
      <div class="user-info">
        <n-dropdown
          :show-arrow="true"
          trigger="click"
          :options="noticeOptions"
          placement="right"
          size="medium"
          :render-label="renderNoticeLabel"
          @select="handleSelectNotice"
        >
          <div class="notice cursor-pointer">
            <n-badge :show="warning !== 0" :value="warning">
              <SvgIcon
                icon="icon_notice"
                color="#cbd3f5"
                size="16px"
                @click="handleOpenNotice"
              ></SvgIcon>
            </n-badge>
          </div>
        </n-dropdown>

        <n-dropdown
          :show-arrow="true"
          placement="right"
          size="small"
          trigger="click"
          :options="options"
          @select="handleSelect"
          :render-label="renderLabel"
        >
          <div class="avator cursor-pointer">
            <n-avatar
              round
              :size="48"
              :src="renderAvatorSrc(userStore.userInfo?.avator as string)"
            />
          </div>
        </n-dropdown>
      </div>
    </div>

    <!-- 通知的panel -->
    <MyDialog
      default-width="35%"
      default-height="90%"
      v-if="dialogs.notice"
      @close="dialogs.notice = false"
    >
      <template #title>
        <div class="flex items-center text-[#555] text-[13px]">
          <SvgIcon icon="icon_notice" class="mr-1"></SvgIcon>
          通知
        </div>
      </template>
      <NoticePanel
        :title="curNotice.title"
        :content="curNotice.content"
        :time="curNotice.time"
      ></NoticePanel>
    </MyDialog>
  </div>
</template>

<script setup lang="ts">
import useUserStore from '@/stores/modules/user'
import useExplorerStore from '@/stores/modules/explorer'
import type { IndexObj } from '@/types/commom'
import type { NoticeRes } from '@/types/notice'
import { getNoticeByPage, getUserNotices, readNotice } from '@/api/notice'
import { PERMISSIONS } from '@/constants/permission'
import { renderAvatorSrc, renderDropLabel } from '@/utils/commonBusiness'
import { formatTime } from '@/utils'
import { useLogout } from '@/hooks/useLogout'
import { useSystemInfo } from '@/hooks/useSystemInfo'
import NoticePanel from './NoticePanel.vue'
import LogoPng from '@/assets/images/7aeab349082b4cfeaa4d4ce094c29978.png'

const { systemInfo } = useSystemInfo()

const userStore = useUserStore()
const explorerStore = useExplorerStore()
const router = useRouter()

const { handleLogout } = useLogout()

const renderCustomHeader = () => {
  return h(
    'div',
    {
      class: 'hover:(bg-gray-100)',
      style:
        'display: flex; align-items: center; padding: 8px 12px;cursor: pointer;',
      onClick: () => {
        router.push({
          name: 'userSettings'
        })
      }
    },
    [
      h(NAvatar, {
        round: true,
        style: 'margin-right: 12px;',
        src: renderAvatorSrc(userStore.userInfo?.avator as string)
      }),
      h('div', null, [
        h('div', null, [
          h(
            NText,
            { depth: 2 },
            { default: () => userStore.userInfo?.role.name || '用户' }
          )
        ]),
        h('div', { style: 'font-size: 12px;' }, [
          h(
            NText,
            { depth: 3 },
            {
              default: () =>
                userStore.userInfo?.nickname ||
                userStore.userInfo?.username ||
                ''
            }
          )
        ])
      ])
    ]
  )
}

const baseOptions = [
  {
    key: 'header',
    type: 'render',
    render: renderCustomHeader
  },
  { key: 'user-account', label: '账号中心', myIcon: 'yonghu1' },

  { key: 'source-manage', label: '文件管理', myIcon: 'wenjianjia1' },
  {
    key: 'd1',
    type: 'divider'
  },
  {
    key: 'backend-manage',
    label: '后台管理',
    myIcon: 'statistics-filled',
    auth: [
      // PERMISSIONS.ADMIN_SETTING,
      PERMISSIONS.ADMIN_DASHBORAD
      // PERMISSIONS.ADMIN_MEMBER_AUTH_MANAGE,
      // PERMISSIONS.DEP_EDIT,
      // PERMISSIONS.DEP_LIST,
      // PERMISSIONS.ROLE_EDIT,
      // PERMISSIONS.ROLE_LIST,
      // PERMISSIONS.AUTH_EDIT,
      // PERMISSIONS.AUTH_LIST,
      // PERMISSIONS.SCHEDULE_EDIT,
      // PERMISSIONS.SCHEDULE_LIST,
      // PERMISSIONS.STORAGE_EDIT,
      // PERMISSIONS.STORAGE_LIST,
      // PERMISSIONS.LOG_MANAGE,
      // PERMISSIONS.LOGIN_LOG_MANAGE
    ]
  },
  {
    key: 'user-manage',
    label: '用户管理',
    myIcon: 'qunzu',
    auth: [PERMISSIONS.DEP_LIST, PERMISSIONS.USER_EDIT, PERMISSIONS.DEP_EDIT]
  },
  {
    key: 'd2',
    type: 'divider'
  },
  { key: 'user-logout', label: '退出', myIcon: 'tuichudenglu' }
]

// 根据用户的权限去过滤掉对应的下拉菜单
const options = computed<IndexObj[]>(() => {
  if (userStore.userInfo) {
    return baseOptions.filter((item) => {
      if (item.auth) {
        return userStore.userInfo!.role.Permissions.some((v) => {
          return item.auth.includes(v.ename)
        })
      } else {
        return true
      }
    })
  } else {
    return baseOptions.filter((item) => !item.auth)
  }
})

const handleSelect = (key: string) => {
  if (key === 'user-account') {
    router.push({
      name: 'userSettings'
    })
  } else if (key === 'source-manage') {
    router.push({
      name: 'explorer'
    })
  } else if (key === 'backend-manage') {
    router.push({
      name: 'overview'
    })
  } else if (key === 'user-manage') {
    router.push({
      name: 'user'
    })
  } else if (key === 'user-logout') {
    handleLogout()
  }
}

const renderLabel = (option: IndexObj) => {
  return renderDropLabel(
    option.myIcon,
    option.label,
    '#888',
    undefined,
    '#b4b4b4'
  )
}

const handleToHome = () => {
  router.push('/')
}

onMounted(async () => {
  if (!userStore.userInfo) {
    await userStore.getUserInfo()
  }
})

// ============================= 通知的相关操作 ===============================
const dialogs = reactive({
  notice: false
})

const handleOpenNotice = () => {
  // dialogs.notice = true
  loadNotice()
}

const curNotice = reactive({
  id: '',
  content: '',
  time: '',
  title: ''
})

const handleSelectNotice = (key: string, option: IndexObj) => {
  curNotice.id = option.id
  curNotice.content = option.content
  curNotice.time = option.createTime
  curNotice.title = option.name
  dialogs.notice = true
  // 该通知被点开，即被读取
  readNotice({
    noticeId: option.id
  })
    .then()
    .catch(console.error)
}

// 获取通知列表进行渲染
const noticeOptions = ref<IndexObj[]>([
  {
    key: 'header',
    label: '消息通知',
    disabled: true
  }
])

onMounted(() => {
  loadNotice()
})

const warning = ref(0)
const loadNotice = () => {
  getUserNotices()
    .then((res) => {
      if (res.data.length) {
        warning.value = 1
      }
      // 将获取到的通知和原有的通知组合起来
      const children = res.data.concat(explorerStore.notices)
      // 去除重复的通知
      const map = new Map()
      for (let i = 0; i < children.length; i++) {
        if (!map.get(children[i].id)) {
          map.set(children[i].id, children[i])
        }
      }
      let notices = []
      for (let [key, value] of map) {
        notices.push(value)
      }
      // 设置给store
      explorerStore.setNotices(notices)
      // 保存到pinia
      noticeOptions.value = [
        {
          type: 'group',
          key: 'header',
          label: '消息通知',
          children: notices.map((item) => {
            return {
              ...item,
              key: item.id,
              label: item.name
            }
          })
        }
      ]
    })
    .catch(console.error)
}

const renderNoticeLabel = (option: IndexObj) => {
  return h(
    'div',
    {
      class: 'flex justify-between w-[260px] text-[13px] items-center h-full'
    },
    option.key === 'header'
      ? [
          h('span', '站内消息通知'),
          h('span', { onClick: handleEmptyNotices }, '清空所有')
        ]
      : [h('span', option.name), h('span', formatTime(option.createTime))]
  )
}

const handleEmptyNotices = () => {
  noticeOptions.value[0].children = []
  explorerStore.cleanNotices()
}
</script>

<style scoped lang="scss">
.left-nav-container {
  min-width: 70px;
  width: 70px;
  display: flex;
  flex-direction: column;
  background: linear-gradient(120deg, #1b6de1, #532a9d);
  background-color: #4f6bdf;
  background-image: linear-gradient(
    180deg,
    #143ad5 0,
    rgba(20, 58, 213, 0) 37%
  );

  .logo {
    width: 100%;
    height: 70px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    background-color: rgba($color: #000000, $alpha: 0.1);
    color: #fff;
  }

  .nav-bar {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;

    .menu-list {
      padding: 5px;
      .item {
        cursor: pointer;
        border-radius: 5px;
        height: 60px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        font-size: 13px;
        color: #fff;

        &.active {
          background-color: rgba(255, 255, 255, 0.25);
        }
      }
    }

    .user-info {
      padding-bottom: 20px;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      align-items: center;

      .notice {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.5s;
      }

      .avator {
        width: 100%;
        height: 70px;
        display: flex;
        align-items: center;
        justify-content: center;
        transition: all 0.5s;
      }

      .notice:hover,
      .avator:hover {
        background-color: rgba(255, 255, 255, 0.25);
      }
    }
  }
}
</style>
